package com.zhongwang.mms.module.buy.service;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.zhongwang.mms.base.BaseService;
import com.zhongwang.mms.common.ImportCallBack;
import com.zhongwang.mms.common.JsonResult;
import com.zhongwang.mms.gen.entity.*;
import com.zhongwang.mms.gen.mapper.BReportPlanChangeMapper;
import com.zhongwang.mms.gen.mapper.BReportPlanMapper;
import com.zhongwang.mms.gen.mapper.BShoppingPlanMapper;
import com.zhongwang.mms.module.basic.dao.TEmployDao;
import com.zhongwang.mms.module.buy.dao.BuyPlanDao;
import com.zhongwang.mms.module.buy.dao.ReportPlanDao;
import com.zhongwang.mms.module.buy.listner.EditAssignReportPlanListener;
import com.zhongwang.mms.module.buy.listner.EditReportPlanListener;
import com.zhongwang.mms.module.buy.listner.ReportPlanListener;
import com.zhongwang.mms.module.buy.model.*;
import com.zhongwang.mms.module.system.log.LogService;
import com.zhongwang.mms.util.CodeUtil;
import com.zhongwang.mms.util.FileUtils;
import com.zhongwang.mms.util.ShiroUtils;
import com.zhongwang.mms.util.StringUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.math.BigDecimal;
import java.util.*;

import static com.zhongwang.mms.util.BeanUtil.copy;

/**
 * @Description: 采购管理 -> 提报计划编辑 Service
 * @Author: China.sgl
 * @Date: 2020/4/7 16:25
 */
@SuppressWarnings("ALL")
@Service
@Log4j2
public class EditReportPlanService extends BaseService {

    @Autowired
    private LogService logService;
    @Autowired
    private ReportPlanDao reportPlanDao;
    @Autowired
    private BReportPlanMapper bReportPlanMapper;
    @Autowired
    private BShoppingPlanMapper bShoppingPlanMapper;
    @Autowired
    private BuyPlanDao buyPlanDao;
    @Autowired
    private BReportPlanChangeMapper bReportPlanChangeMapper;
    @Autowired
    private TEmployDao tEmployDao;

    @Value("${user.upload.path}")
    private String uploadPath;

    private String msg = "";

    /**
     * 查询计划员列表
     *
     * @return list
     */
    public List<TEmploy> findPlannerList() {
        return reportPlanDao.findEmployByStatus(1);
    }

    /**
     * 查询分类字典数据
     *
     * @return list
     */
    public List<TDictionary> findTypes() {
        return reportPlanDao.findDictionaryByTypeAndStatus(1000, 1);
    }

    /**
     * 按条件查询提报计划
     *
     * @param reportPlanModel 条件
     * @return list
     */
    public List<ReportPlanModel> findReportPlanByQuery(ReportPlanModel reportPlanModel) {
        List<ReportPlanModel> list = null ;
        try {
            if (reportPlanModel.getRppMatDescArrayStr() != null && !reportPlanModel.getRppMatDescArrayStr().equals("")) {
                String[] strArray = reportPlanModel.getRppMatDescArrayStr().split(",");
                reportPlanModel.setRppMatDescArray(Arrays.asList(strArray));
            }
            if (reportPlanModel.getRppProjectCodeArrayStr() != null && !reportPlanModel.getRppProjectCodeArrayStr().equals("")) {
                String[] strArray = reportPlanModel.getRppProjectCodeArrayStr().split(",");
                reportPlanModel.setRppProjectCodeArray(Arrays.asList(strArray));
            }
            list = reportPlanDao.findReportPlanByQueryWithEdit(reportPlanModel);
        }catch (Exception e){
            e.printStackTrace();
        }
        return list;
    }
    /**  findReportPlanBatchChangeListByQuery 获取批量修改状态列表
     * @param reportPlanModel
     * @return java.util.List<com.zhongwang.mms.module.buy.model.ReportPlanModel>
     * @author 徐一贺
     * @date 2020/12/30 9:49
     */
    public List<ReportPlanModel> findReportPlanBatchChangeListByQuery(ReportPlanModel reportPlanModel) {
        List<ReportPlanModel> list = null;
        try {
            if (reportPlanModel.getRppMatDescArrayStr() != null && !reportPlanModel.getRppMatDescArrayStr().equals("")) {
                String[] strArray = reportPlanModel.getRppMatDescArrayStr().split(",");
                reportPlanModel.setRppMatDescArray(Arrays.asList(strArray));
            }
            if (reportPlanModel.getRppProjectCodeArrayStr() != null && !reportPlanModel.getRppProjectCodeArrayStr().equals("")) {
                String[] strArray = reportPlanModel.getRppProjectCodeArrayStr().split(",");
                reportPlanModel.setRppProjectCodeArray(Arrays.asList(strArray));
            }
            list = reportPlanDao.findReportPlanBatchChangeListByQuery(reportPlanModel);
        }catch (Exception e){
            e.printStackTrace();
        }
        return list;
    }

//    public JsonResult getRppIsChangeStatusFlagCount(ReportPlanModel reportPlanModel) {
//        JsonResult jsonResult = new JsonResult();
//        try {
//            if (reportPlanModel.getRppMatDescArrayStr() != null && !reportPlanModel.getRppMatDescArrayStr().equals("")) {
//                String[] strArray = reportPlanModel.getRppMatDescArrayStr().split(",");
//                reportPlanModel.setRppMatDescArray(Arrays.asList(strArray));
//            }
//            if (reportPlanModel.getRppProjectCodeArrayStr() != null && !reportPlanModel.getRppProjectCodeArrayStr().equals("")) {
//                String[] strArray = reportPlanModel.getRppProjectCodeArrayStr().split(",");
//                reportPlanModel.setRppProjectCodeArray(Arrays.asList(strArray));
//            }
//            List<ReportPlanModel> result = reportPlanDao.getRppIsChangeStatusFlagCount(reportPlanModel);
//            jsonResult.setType(JsonResult.ResultType.SUCCESS);
//            jsonResult.setData(result);
//            return jsonResult;
//        } catch (Exception e) {
//            e.printStackTrace();
//            jsonResult.setType(JsonResult.ResultType.ERROR);
//            jsonResult.setMsg("获取失败");
//            return jsonResult;
//        }
//    }

    /**
     * 查询项目号是否存在
     *
     * @param code 项目号
     * @return boolean
     */
    public boolean findProjectCode(String code) {
        return reportPlanDao.findProjectByCode(code) != null;
    }

    /**
     * 添加提报计划
     *
     * @param reportPlan 计划信息
     * @return 行数
     */
    public int insertReportPlan(ReportPlanModel reportPlan) {
        if (reportPlan.getRppPlanner() == null || reportPlan.getRppMatDesc() == null
                || reportPlan.getRppNum() == null || reportPlan.getRppUnit() == null
                || reportPlan.getRppProjectCode() == null || reportPlan.getRppProjectName() == null
                || reportPlanDao.findExist(reportPlan) > 0) {
            return 0;
        }
        TDictionary category = reportPlanDao.findDictionaryByIdAndStatus(reportPlan.getRppTypeId(), 1);
        reportPlan.setRppProjectCode(CodeUtil.projectCodeHandle(reportPlan.getRppProjectCode()));
        reportPlan.setRppTypes(category.getDicName());
        reportPlan.setRppCreateTime(new Date());
        reportPlan.setRppOriginalFlag(1);
        reportPlan.setRppStatus(2);
        reportPlan.setRppAllowCancel(2);
        reportPlan.setRppAppend(0);
        reportPlan.setRppCreateUser(ShiroUtils.getUser().getName());
        reportPlan.setRppIsFlag(0);
        reportPlanDao.insert(reportPlan);
        return logService.saveLog("提报计划添加", "添加提报计划");
    }

    /**
     * 导入提报计划
     *
     * @param file 导入文件
     * @return
     */
    //@Transactional(rollbackFor = Exception.class)
    public String importFile(MultipartFile file) {

        try {
            FileUtils.importExcel(file, ReportPlanModel.class, new ReportPlanListener(reportPlanDao, new ImportCallBack() {
                @Override
                public void onSuccess() {
                    msg = "导入完成";
                }

                @Override
                public void onWarning(List list) {
                    msg = "部份数据无法导入，请点击下载检查数据内容";
                    exportErrorExcel(list);
                }
            }, reportPlanDao.findDictionaryByTypeAndStatus(1000, 1), reportPlanDao.findEmployByStatus(1)));
        } catch (Exception e) {
            return "导入失败";
        }
        logService.saveLog("提报计划编辑", "导入提报计划");
        return msg;
    }

    /**
     * 异常数据导出到Excel
     *
     * @param errorList
     */
    private void exportErrorExcel(List<ReportPlanModel> errorList) {
        if (errorList.size() <= 0) {
            return;
        }
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        String path = uploadPath + user.getAccount() + "/";
        FileUtils.genExcel(path, "error.xls", ReportPlanModel.class, "未成功导入数据", errorList);
    }

    /**
     * 判断文件是否存在
     *
     * @param url 文件URL
     * @return 是否存在
     */
    public boolean exist(String url) {
        int i = url.lastIndexOf("files/");
        String path = uploadPath + url.substring(i + 6);
        File file = new File(path);
        if (!file.exists()) {
            return false;
        }
        return true;
    }


    /**
     * 根据主键查询提报计划
     *
     * @param id 主键
     * @return ReportPlanModel
     */
    public ReportPlanModel findReportPlanById(Integer id) {
        return reportPlanDao.findReportPlanById(id);
    }

    /**
     * 查询并保存日志
     *
     * @param id   主键
     * @param name 日志名称
     */
    private void saveLog(Integer id, String name) {
        ReportPlanModel plan = findReportPlanById(id);
        logService.saveLog(name, "项目名：" + plan.getRppProjectName() + "<br>物料描述：" + plan.getRppMatDesc());
    }

    /**
     * 删除提报计划, 待审状态
     *
     * @param id     主键
     * @param reason 删除原因
     * @return 行数
     */
    public int deleteById(Integer id, String reason) {
        saveLog(id, "删除提报计划");
        return reportPlanDao.updateStatusAndReasonById(id, 1, reason);
    }

    /**
     * 修改提报计划
     *
     * @param reportPlan 提报计划
     * @return 行数
     */
    public int updateReportPlan(BReportPlan reportPlan) {
        try {
            BReportPlan before = bReportPlanMapper.selectByPrimaryKey(reportPlan.getRppId());
            BReportPlan after = new BReportPlan();
            copy(before, after);
            copy(reportPlan, after);
            // 设置分类名称
            TDictionary category = reportPlanDao.findDictionaryByIdAndStatus(after.getRppTypeId(), 1);
            after.setRppTypes(category.getDicName());
            // 保存日志
            logService.saveLog("修改提报计划", before, after);
            if (reportPlan.getRppUseStock() != null && before.getRppUseStock() != null && !before.getRppUseStock().equals(reportPlan.getRppUseStock())) {
                after.setRppEditTime(new Date());
            } else if (reportPlan.getRppUseStock() == null && before.getRppUseStock() != null) {
                after.setRppEditTime(new Date());
            } else {
                after.setRppEditTime(null);
            }
            after.setRppUseStock(reportPlan.getRppUseStock());
            reportPlanDao.update(after);
            return 1;
        }catch (Exception e){
            e.printStackTrace();
        }
        return 0;
    }


    /**
     * 修改提报计划状态， 生成日志
     *
     * @param id     主键
     * @param status 状态
     * @param name   日志操作名称
     * @return 行数
     */
    private int updateReportPlanStatus(Integer id, Integer status, String name) {
        ReportPlanModel plan = findReportPlanById(id);
        logService.saveLog(name, "项目名：" + plan.getRppProjectName() + "<br>物料描述：" + plan.getRppMatDesc());
        return reportPlanDao.updateStatusById(id, status);
    }

    /**
     * 提交提报计划
     *
     * @param id 主键
     * @return 行数
     */
    public int commitById(Integer id) {
        ReportPlanModel plan = findReportPlanById(id);
        logService.saveLog("提交提报计划", "项目名：" + plan.getRppProjectName() + "<br>物料描述：" + plan.getRppMatDesc());
        return reportPlanDao.updateStatusAndCommitTimeById(id, 3, new Date());
    }

    /**
     * 批量提交提报计划
     *
     * @param rppIds 提报计划ID数组
     * @return 行数
     */
    @Transactional(rollbackFor = Exception.class)
    public int commitInId(Integer[] rppIds) {
        int count = 0;
        // 保存日志，生成采购计划
        for (Integer rppId : rppIds) {
            count += commitById(rppId);
        }
        return count == rppIds.length ? 1 : 0;
    }


    /**
     * 撤消提报计划, 正常提报类型需要先删除采购计划
     *
     * @param id 主键
     * @return 行数
     */
    @Transactional(rollbackFor = Exception.class)
    public int cancel(Integer id) {

        ReportPlanModel reportPlan = findReportPlanById(id);
        logService.saveLog("撤消提报计划", "项目名：" + reportPlan.getRppProjectName() + "<br>物料描述：" + reportPlan.getRppMatDesc());
        // 正常采购并且采购计划未提交
        if (reportPlan.getRppUseStock() == 2 && (reportPlan.getSppStatus() == null || reportPlan.getSppStatus().equals(0) || reportPlan.getSppStatus().equals(1))) {
            buyPlanDao.updateStatusById(reportPlan.getRppSppId(), 0);
            return reportPlanDao.updateStatusAndCommitTimeById(id, 2, null);
        } else {
            return 0;
        }
    }

    /**
     * 撤消提报计划, 正常提报类型需要先删除采购计划
     *
     * @param rppIds 主键们
     * @return 行数
     */
    @Transactional(rollbackFor = Exception.class)
    public int cancels(Integer[] rppIds) {
        int result = 0;
        for (Integer id : rppIds) {
            ReportPlanModel reportPlan = findReportPlanById(id);
            logService.saveLog("撤消提报计划", "项目名：" + reportPlan.getRppProjectName() + "<br>物料描述：" + reportPlan.getRppMatDesc());
            // 正常采购并且采购计划未提交
            if (reportPlan.getRppUseStock() == 2 && (reportPlan.getSppStatus() == null || reportPlan.getSppStatus() == 1)) {
                buyPlanDao.updateStatusById(reportPlan.getRppSppId(), 0);
                result += reportPlanDao.updateStatusAndCommitTimeById(id, 2, null);
            } else {
                result = result + 0;
            }
        }
        return result;
    }

    ///**
    // * 拆分提报计划
    // * 不添加数量或描述为空的记录， 如果没有符合条件的拆分数据返回失败。
    // * 拆分原记录如果为已拆分过的记录， 直接删除， 拆分后的记录原提报计划指定根计划
    // * 拆分原记录如果为原始计划，修改状态为已被拆分的原始计划
    // *
    // * @param rppId  被拆分的提报计划ID
    // * @param num    拆分的数量数组
    // * @param status 提报状态数组
    // * @param remark 备注数组
    // * @param desc   物料描述数组
    // * @return 行数
    // */
    //@Transactional(rollbackFor = Exception.class)
    //public int splitReportPlan(Integer rppId, Double[] num, Integer[] status, String[] remark, String[] desc) {
    //    ReportPlanModel reportPlan = findReportPlanById(rppId);
    //    int count = 0;
    //    BReportPlan bReportPlan;
    //    for (int i = 0; i < num.length; i++) {
    //        if (num[i] == null || desc[i] == null) {
    //            continue;
    //        }
    //        bReportPlan = new BReportPlan();
    //        copy(reportPlan, bReportPlan);
    //        bReportPlan.setRppMatDesc(desc[i]);
    //        bReportPlan.setRppNum(num[i]);
    //        bReportPlan.setRppUseStock(status[i]);
    //        bReportPlan.setRppRemark(remark[i]);
    //        bReportPlan.setRppSrcId(reportPlan.getRppSrcId() == null ? rppId : reportPlan.getRppSrcId());
    //        bReportPlan.setRppOriginalFlag(2);
    //        bReportPlan.setRppSplitPlanType("new");
    //        count += bReportPlanMapper.insert(bReportPlan);
    //    }
    //    if (count == 0) {
    //        return 0;
    //    }
    //    logService.saveLog("拆分提报计划", "项目名：" + reportPlan.getRppProjectName() + "<br>物料描述：" + reportPlan.getRppMatDesc());
    //    if (reportPlan.getRppSrcId() == null) {
    //        reportPlanDao.updateOriginalById(rppId, 3);
    //    } else {
    //        bReportPlanMapper.deleteByPrimaryKey(rppId);
    //    }
    //
    //    if (reportPlan.getRppSplitPlanType().equals("new")) {
    //        reportPlanDao.updateRppSplitPlanTypeById(rppId, "old");
    //    }else if (reportPlan.getRppSplitPlanType().equals("source")) {
    //        reportPlanDao.updateRppSplitPlanTypeById(rppId, "oldSource");
    //    }
    //    return 1;
    //}

    /**
     * 拆分提报计划
     * 未拆分的计划是原始计划，当原始计划被拆分，则原始计划称为旧原始计划，
     * 拆分出来的为新计划，当被拆分的计划为新计划，则新计划变成旧计划，拆分出来的为新计划
     * 使数据格式为
     * 主键：1 描述：钢笔 数量单位：100支 拆分身份：原计划 提报类型：无状态   父级ID：NULL 祖先ID：NULL 拆分标识：3
     * 主键：2 描述：钢笔 数量单位：18支  拆分身份：新计划 提报类型：正常提报 父级ID：1    祖先ID：1    拆分标识：2
     * 主键：3 描述：钢笔 数量单位：2支   拆分身份：新计划 提报类型：使用库存 父级ID：1    祖先ID：1    拆分标识：2
     * 主键：4 描述：钢笔 数量单位：80支  拆分身份：旧计划 提报类型：暂不提报 父级ID：1    祖先ID：1    拆分标识：3
     * 主键：5 描述：钢笔 数量单位：50支  拆分身份：新计划 提报类型：正常提报 父级ID：4    祖先ID：1    拆分标识：2
     * 主键：6 描述：钢笔 数量单位：30支  拆分身份：新计划 提报类型：暂不提报 父级ID：4    祖先ID：1    拆分标识：2
     *
     * @param rppId  被拆分的提报计划ID
     * @param num    拆分的数量数组
     * @param status 提报状态数组
     * @param remark 备注数组
     * @param desc   物料描述数组
     * @return 行数
     */
    @Transactional(rollbackFor = Exception.class)
    public int splitReportPlan(Integer rppId, Double[] num, Integer[] status, String[] remark, String[] desc) {
        ReportPlanModel reportPlan = findReportPlanById(rppId);
        int count = 0;
        BReportPlan bReportPlan;
        for (int i = 0; i < num.length; i++) {
            if (num[i] == null || desc[i] == null) {
                continue;
            }
            bReportPlan = new BReportPlan();
            copy(reportPlan, bReportPlan);
            bReportPlan.setRppMatDesc(desc[i]);
            bReportPlan.setRppNum(num[i]);
            bReportPlan.setRppUseStock(status[i]);
            bReportPlan.setRppRemark(remark[i]);
            bReportPlan.setRppSrcId(rppId);
            bReportPlan.setRppOriginalFlag(2);
            bReportPlan.setRppSplitPlanType("new");
            if (reportPlan.getRppAncestorsId() != null) {
                bReportPlan.setRppAncestorsId(reportPlan.getRppAncestorsId());
            } else {
                bReportPlan.setRppAncestorsId(rppId);
            }

            count += bReportPlanMapper.insert(bReportPlan);
        }
        if (count == 0) {
            return 0;
        }
        logService.saveLog("拆分提报计划", "项目名：" + reportPlan.getRppProjectName() + "<br>物料描述：" + reportPlan.getRppMatDesc());
        reportPlanDao.updateOriginalById(rppId, 3);
        if (reportPlan.getRppSplitPlanType().equals("new")) {
            reportPlanDao.updateRppSplitPlanTypeById(rppId, "old");
        } else if (reportPlan.getRppSplitPlanType().equals("source")) {
            reportPlanDao.updateRppSplitPlanTypeById(rppId, "oldSource");
        }
        return 1;
    }

    /**
     * 变更提报计划，
     *
     * @param reportPlan 提报计划
     * @return 行数
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult changeReportPlan(BReportPlan reportPlan) {
        JsonResult jsonResult = new JsonResult();
        TEmploy param = new TEmploy();
        param.setEmpName(reportPlan.getRppPlanner());
        param.setEmpStatus(1);
        TEmploy tEmploy = tEmployDao.getByCondition(param);
        if (tEmploy == null) {
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("计划员不存在！");
        } else {
            BReportPlan srcPlan = bReportPlanMapper.selectByPrimaryKey(reportPlan.getRppId());
            BReportPlan before = new BReportPlan();
            copy(srcPlan, before);

            logService.saveLog("变更提报计划", before, srcPlan);
            if (!StringUtils.replaceBlank(before.getRppMatDesc().trim()).equals(reportPlan.getRppMatDesc().trim())) {
                srcPlan.setRppChangeMark(1);
            }
            srcPlan.setRppChangeMark(1);
            srcPlan.setRppChangeTime(new Date());
            // 修改提报计划
            copy(reportPlan, srcPlan);
            bReportPlanMapper.updateByPrimaryKey(srcPlan);
            if (!StringUtils.replaceBlank(before.getRppMatDesc().trim()).equals(srcPlan.getRppMatDesc().trim())) {
                // 创建变更记录
                BReportPlanChange reportPlanChange = new BReportPlanChange();
                reportPlanChange.setRpcMatCode(srcPlan.getRppMatCode());
                reportPlanChange.setRpcMatDesc(srcPlan.getRppMatDesc());
                reportPlanChange.setRpcBrand(srcPlan.getRppBrand());
                reportPlanChange.setRpcDesigner(srcPlan.getRppDesigner());
                reportPlanChange.setRpcChangeTime(new Date());
                reportPlanChange.setRpcNum(srcPlan.getRppNum());
                reportPlanChange.setRpcOverNum(srcPlan.getRppOverNum());
                reportPlanChange.setRpcUnit(srcPlan.getRppUnit());
                reportPlanChange.setRpcTypeId(srcPlan.getRppTypeId());
                reportPlanChange.setRpcTrackCode(null);
                reportPlanChange.setRpcTel(srcPlan.getRppDesignerTel());
                reportPlanChange.setRpcStandardNo(srcPlan.getRppStandardNo());
                reportPlanChange.setRpcRppId(srcPlan.getRppId());
                reportPlanChange.setRpcRemark(srcPlan.getRppRemark());
                reportPlanChange.setRpcReason(srcPlan.getRppChange());
                reportPlanChange.setRpcRealNum(srcPlan.getRppRealNum());
                reportPlanChange.setRpcProjectName(srcPlan.getRppProjectName());
                reportPlanChange.setRpcProjectCode(srcPlan.getRppProjectCode());
                reportPlanChange.setRpcPlanner(srcPlan.getRppPlanner());
                reportPlanChange.setRpcPart(srcPlan.getRppPart());
                reportPlanChange.setRpcDiagram(srcPlan.getRppDiagram());
                reportPlanChange.setRpcAssistType(srcPlan.getRppAssistType());
                reportPlanChange.setRpcUseStore(srcPlan.getRppUseStore());
                reportPlanChange.setRpcNewUnit(reportPlan.getRppUnit());
                reportPlanChange.setRpcNewTypeId(reportPlan.getRppTypeId());
                reportPlanChange.setRpcNewTel(reportPlan.getRppDesignerTel());
                reportPlanChange.setRpcNewStandardNo(reportPlan.getRppStandardNo());
                reportPlanChange.setRpcNewRemark(reportPlan.getRppRemark());
                reportPlanChange.setRpcNewRealNum(reportPlan.getRppRealNum());
                reportPlanChange.setRpcNewProjectName(reportPlan.getRppProjectName());
                reportPlanChange.setRpcNewProjectCode(reportPlan.getRppProjectCode());
                reportPlanChange.setRpcNewPlanner(reportPlan.getRppPlanner());
                reportPlanChange.setRpcNewPart(reportPlan.getRppPart());
                reportPlanChange.setRpcNewOverNum(reportPlan.getRppOverNum());
                reportPlanChange.setRpcNewNum(reportPlan.getRppNum());
                reportPlanChange.setRpcNewMatDesc(reportPlan.getRppMatDesc());
                reportPlanChange.setRpcNewMatCode(reportPlan.getRppMatCode());
                reportPlanChange.setRpcNewDesigner(reportPlan.getRppDesigner());
                reportPlanChange.setRpcNewBrand(reportPlan.getRppBrand());
                reportPlanChange.setRpcNewDiagram(srcPlan.getRppDiagram());
                reportPlanChange.setRpcNewAssistType(srcPlan.getRppAssistType());
                reportPlanChange.setRpcNewUseStore(srcPlan.getRppUseStore());
                bReportPlanChangeMapper.insert(reportPlanChange);
            }
            jsonResult.setType(JsonResult.ResultType.SUCCESS);
            jsonResult.setMsg("变更成功！");
        }
        return jsonResult;


    }

    /**
     * 查询标记列表
     *
     * @param stockMarkModel 条件
     * @return List
     */
    public List<StockMarkModel> findMarkList(StockMarkModel stockMarkModel) {
        return reportPlanDao.findMarkList(stockMarkModel);
    }

    /**
     * 指定标记, 清除六张标记表已存在的提报计划ID， 再根据参数配置提报计划ID
     *
     * @param rppId 提报计划ID
     * @param id    标记ID
     * @return 行数
     */
    @Transactional(rollbackFor = Exception.class)
    public int mark(Integer rppId, String idStr) {
        ReportPlanModel model = new ReportPlanModel();
        //获取提报计划
        BReportPlan bdReportPlan = reportPlanDao.getById(rppId);
        // 清空原指定关系
        reportPlanDao.updatePchangeOrderRppId(rppId);
        reportPlanDao.updateMchangeOrderRppId(rppId);
        reportPlanDao.updateHchangeOrderRppId(rppId);
        reportPlanDao.updatePinventoryProjectMarkRppId(rppId);
        reportPlanDao.updateMinventoryProjectMarkRppId(rppId);
        reportPlanDao.updateHinventoryProjectMarkRppId(rppId);
        String[] id = idStr.split("☯");
        Double totalNum = 0d;
        String unit = "";
        Double totalPrice = 0d;
        model.setRppItyType("");
        for (String s : id) {
            String[] split = s.split("###");
            switch (split[0]) {
                case "p_change_order":
                    reportPlanDao.updatePchangeOrder(rppId, split[1]);
                    //平均单价
                    Double pChangeOrderPrice = reportPlanDao.getPInventoryPriceForPurChangeByCeoRppId(rppId);
                    //总数量
                    Double numPurChange = reportPlanDao.getTotalNumForPurChangeByCeoRppId(rppId);
                    totalNum += numPurChange;
                    //获取总价格
                    totalPrice += numPurChange * pChangeOrderPrice;
                    //单位
                    if ("".equals(unit)) {
                        unit = reportPlanDao.getUnitForPurChangeByCeoRppId(rppId);
                    }
//                    reportPlanDao.updateBReportPlanRppAssignUseStockPrice(rppId, pChangeOrderPrice, new Date());
                    PInventory pInventoryForPChangeOradr = reportPlanDao.getPInventoryByRppId(rppId);
                    reportPlanDao.updateBReportPlanRppSapCodeAndRppBuyStockMatDesc(rppId, pInventoryForPChangeOradr.getItySapCode(), pInventoryForPChangeOradr.getItyMatDesc());
                    if (!model.getRppItyType().contains("p")) {
                        model.setRppItyType(model.getRppItyType() + "p,");
                    }
                    break;
                case "p_inventory_project_mark":
                    reportPlanDao.updatePinventoryProjectMark(rppId, split[1]);
                    Double pInventoryProjectMarkPrice = reportPlanDao.getPInventoryPriceForPInventoryProjectMarkByIpmRppId(rppId);
                    //总数量
                    Double numPInventoryProjectMark = reportPlanDao.getTotalNumForPInventoryProjectMarkByIpmRppId(rppId);
                    totalNum += numPInventoryProjectMark;
                    totalPrice += numPInventoryProjectMark * pInventoryProjectMarkPrice;
                    //单位
                    if ("".equals(unit)) {
                        unit = reportPlanDao.getUnitForPInventoryProjectMarkByIpmRppId(rppId);
                    }
//                    reportPlanDao.updateBReportPlanRppAssignUseStockPrice(rppId, pInventoryProjectMarkPrice, new Date());
                    PInventory pInventoryForPInventoryProjectMark = reportPlanDao.getPInventoryFromPInventoryProjectMarkByRppId(rppId);
                    reportPlanDao.updateBReportPlanRppSapCodeAndRppBuyStockMatDesc(rppId, pInventoryForPInventoryProjectMark.getItySapCode(), pInventoryForPInventoryProjectMark.getItyMatDesc());
                    if (!model.getRppItyType().contains("p")) {
                        model.setRppItyType(model.getRppItyType() + "p,");
                    }
                    break;
                case "m_change_order":
                    reportPlanDao.updateMchangeOrder(rppId, split[1]);
                    Double mChangeOrderPrice = reportPlanDao.getMInventoryPriceForMatChangeByCeoRppId(rppId);
                    //总数量
                    Double numMatChange = reportPlanDao.getTotalNumForMatChangeByCeoRppId(rppId);
                    totalNum += numMatChange;
                    totalPrice += numMatChange * mChangeOrderPrice;
                    //单位
                    if ("".equals(unit)) {
                        unit = "千克";
                    }
//                    reportPlanDao.updateBReportPlanRppAssignUseStockPrice(rppId, mChangeOrderPrice, new Date());
                    MInventory mInventoryForPChangeOradr = reportPlanDao.getMInventoryForPChangeOrderByRppId(rppId);
                    reportPlanDao.updateBReportPlanRppSapCodeAndRppBuyStockMatDesc(rppId, mInventoryForPChangeOradr.getItyMatSapCode(), reportPlanDao.getMMatDescByMatId(mInventoryForPChangeOradr.getItyMatId()));
                    if (!model.getRppItyType().contains("m")) {
                        model.setRppItyType(model.getRppItyType() + "m,");
                    }
                    break;
                case "m_inventory_project_mark":
                    reportPlanDao.updateMinventoryProjectMark(rppId, split[1]);
                    Double mInventoryProjectMarkPrice = reportPlanDao.getMInventoryPriceForMInventoryProjectMarkByIpmRppId(rppId);
                    //总数量
                    Double numMInventoryProjectMark = reportPlanDao.getTotalNumForMInventoryProjectMarkByIpmRppId(rppId);
                    totalNum += numMInventoryProjectMark;
                    totalPrice += mInventoryProjectMarkPrice * numMInventoryProjectMark;
                    //单位
                    if ("".equals(unit)) {
                        unit = "千克";
                    }
//                    reportPlanDao.updateBReportPlanRppAssignUseStockPrice(rppId, mInventoryProjectMarkPrice, new Date());
                    MInventory mInventoryForMInventoryProjectMark = reportPlanDao.getMInventoryForMInventoryForMInventoryProjectMarkByRppId(rppId);
                    reportPlanDao.updateBReportPlanRppSapCodeAndRppBuyStockMatDesc(rppId, mInventoryForMInventoryProjectMark.getItyMatSapCode(), reportPlanDao.getMMatDescByMatId(mInventoryForMInventoryProjectMark.getItyMatId()));
                    if (!model.getRppItyType().contains("m")) {
                        model.setRppItyType(model.getRppItyType() + "m,");
                    }
                    break;
                case "h_change_order":
                    reportPlanDao.updateHchangeOrder(rppId, split[1]);
                    Double hChangeOrderPrice = reportPlanDao.getHInventoryPriceForHalfChangeByCeoRppId(rppId);
                    //总数量
                    Double numHalfChange = reportPlanDao.getTotalNumForHalfChangeByCeoRppId(rppId);
                    totalNum += numHalfChange;
                    totalPrice += hChangeOrderPrice * numHalfChange;
                    //单位
                    if ("".equals(unit)) {
                        unit = reportPlanDao.getUnitForHalfChangeByCeoRppId(rppId);
                    }
//                    reportPlanDao.updateBReportPlanRppAssignUseStockPrice(rppId, hChangeOrderPrice, new Date());
                    HInventory hInventoryForPChangeOradr = reportPlanDao.getHInventoryForPChangeOradrByRppId(rppId);
                    reportPlanDao.updateBReportPlanRppSapCodeAndRppBuyStockMatDesc(rppId, hInventoryForPChangeOradr.getItySapCode(), hInventoryForPChangeOradr.getItyMatName());
                    if (!model.getRppItyType().contains("h")) {
                        model.setRppItyType(model.getRppItyType() + "h,");
                    }
                    break;
                case "h_inventory_project_mark":
                    reportPlanDao.updateHinventoryProjectMark(rppId, split[1]);
                    Double hInventoryProjectMarkPrice = reportPlanDao.getHInventoryPriceForHInventoryProjectMarkByIpmRppId(rppId);
                    //总数量
                    Double numHInventoryProjectMark = reportPlanDao.getTotalNumForHInventoryProjectMarkByIpmRppId(rppId);
                    totalNum += numHInventoryProjectMark;
                    totalPrice += hInventoryProjectMarkPrice * numHInventoryProjectMark;
                    //单位
                    if ("".equals(unit)) {
                        unit = reportPlanDao.getUnitForHInventoryProjectMarkByIpmRppId(rppId);
                    }
//                  reportPlanDao.updateBReportPlanRppAssignUseStockPrice(rppId, hInventoryProjectMarkPrice, new Date());
                    HInventory hInventoryForMInventoryProjectMark = reportPlanDao.getHInventoryForMInventoryProjectMarkByRppId(rppId);
                    reportPlanDao.updateBReportPlanRppSapCodeAndRppBuyStockMatDesc(rppId, hInventoryForMInventoryProjectMark.getItySapCode(), hInventoryForMInventoryProjectMark.getItyMatName());
                    if (!model.getRppItyType().contains("h")) {
                        model.setRppItyType(model.getRppItyType() + "h,");
                    }
                    break;
                default:
            }
        }
        if (bdReportPlan.getRppNum().doubleValue() == totalNum.doubleValue() && bdReportPlan.getRppUnit().equals(unit)) {
            reportPlanDao.updateBReportPlanRppAssignUseStockPrice(rppId, new BigDecimal(totalPrice).divide(new BigDecimal(totalNum), 2, BigDecimal.ROUND_HALF_UP).doubleValue(), new Date());
        } else {
            reportPlanDao.updateBReportPlanRppAssignUseStockPrice(rppId, null, new Date());
        }
        reportPlanDao.updateBReportPlanUseStockNumAndUnit(rppId, totalNum, unit);
        saveLog(rppId, "指定库存");
        model.setRppId(rppId);
        model.setRppAssignDesc(reportPlanDao.getById(rppId).getRppAssignDesc());
        model.setRppIsFlag(1);
        model.setRppAssignDate(new Date());

        return reportPlanDao.updateIsFlagAndAssignDesc2ById(model);
    }

    /**
     * 提报计划关系查询
     *
     * @param reportPlanModel 条件
     * @return list
     */
    public List<ReportPlanModel> findReportPlanMapByQuery(ReportPlanModel reportPlanModel) {
        return reportPlanDao.findReportPlanSplitInfoByQuery(reportPlanModel);
    }

    /**
     * 根据ID查询提报计划指定信息
     *
     * @param id 提报计划主键
     * @return list
     */
    public List<StockMarkModel> findAssignInfoById(Integer id) {
        return reportPlanDao.findAssignInfoById(id);
    }

    /**
     * 修改计划员
     *
     * @param reportPlan 提报计划
     * @return 行数
     */
    public int updatePlanner(BReportPlan reportPlan) {
        return bReportPlanMapper.updateByPrimaryKeySelective(reportPlan);
    }

    /**
     * 批量修改提报状态
     *
     * @param rppIds ID数组
     * @param status 状态
     * @return 行数
     */
    public int batchStatus(Integer[] rppIds, Integer status) {
        logService.saveLog("批量修改", "批量修改提报状态");
        int count = 0;
        // 保存日志，生成采购计划
        for (Integer rppId : rppIds) {
            count += reportPlanDao.updateUseStockById(rppId, status);
        }
        return count == rppIds.length ? 1 : 0;
    }

    /**
     * 指定提报计划描述
     *
     * @param reportPlanModel 计划
     * @return 行数
     */
    public int assign(ReportPlanModel reportPlanModel) {
        int result = 0;
        try {
            BReportPlan sourcePlan = reportPlanDao.getById(reportPlanModel.getRppId());
            if (reportPlanModel.getRppDiyAssignUseStockNum().doubleValue() != sourcePlan.getRppNum().doubleValue() ||
                    !reportPlanModel.getRppDiyAssignUseStockUnit().equals(sourcePlan.getRppUnit())) {
                reportPlanModel.setRppAssignUseStockPrice(null);
            }
            reportPlanModel.setRppIsFlag(1);
            reportPlanModel.setRppAssignDate(new Date());
            result = reportPlanDao.updateIsFlagAndAssignDescById(reportPlanModel);
            sourcePlan = reportPlanDao.getById(reportPlanModel.getRppId());
            logService.saveLog("手动指定", "项目号：【" + sourcePlan.getRppProjectCode() +
                    "】，项目名称：【" + sourcePlan.getRppProjectName() +
                    "】，物料名称：【" + sourcePlan.getRppMatDesc() +
                    "】，提报数量：【" + sourcePlan.getRppNum() +
                    "】，单位：【" + sourcePlan.getRppUnit() +
                    "】，指定内容如下：<BR>物料描述【" + sourcePlan.getRppAssignDesc() +
                    "】，数量：【" + sourcePlan.getRppNum() +
                    "】，单位：【" + sourcePlan.getRppDiyAssignUseStockNum() +
                    "】，单价：【" + (sourcePlan.getRppAssignUseStockPrice() == null ? "" : sourcePlan.getRppAssignUseStockPrice()) +
                    "】<font color='red'><b>注：当指定数量与单位与提报计划不同时则无法记录单价。</b></font>");
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
        return result;
    }

//    /**
//     * 提报计划导出
//     *
//     * @param response        输出流
//     * @param reportPlanModel 条件
//     */
//    public void export(HttpServletResponse response, ReportPlanModel reportPlanModel) {
//        reportPlanModel.setRppPlanner(ShiroUtils.getUser().getName());
//        String path = uploadPath + ShiroUtils.getLoginName() + "/";
//        List<ExportReportPlanModel> list = reportPlanDao.findByQueryWithExport(reportPlanModel);
//        for (ExportReportPlanModel model : list) {
//            switch (model.getRppUseStock()) {
//                case 0:
//                    model.setRppReportStatus("无状态");
//                    break;
//                case 1:
//                    model.setRppReportStatus("使用库存");
//                    break;
//                case 2:
//                    model.setRppReportStatus("正常提报");
//                    break;
//                case 3:
//                    model.setRppReportStatus("暂不提报");
//                    break;
//                default:
//
//            }
//            if (model.getRppAppend() == 1) {
//                model.setRppAppendStr("是");
//            } else {
//                model.setRppAppendStr("否");
//            }
//        }
//        FileUtils.export(path, "提报计划.xls", ExportReportPlanModel.class, "sheet1", list, response);
//    }

    /**
     * 拆分 -> 导入批量拆分的数据
     *
     * @param file 文件
     * @return 描述
     */
    public String importAndEdit(MultipartFile file) {
        try {
            FileUtils.importExcel(file, ExportDeferralModel.class, new EditReportPlanListener(reportPlanDao, new ImportCallBack() {
                @Override
                public void onSuccess() {
                    msg = "导入完成";
                }

                @Override
                public void onWarning(List list) {
                    msg = "部份数据无法导入，请点击下载检查数据内容";
                    exportErrorExcelWithSplit(list);
                }
            }, bReportPlanChangeMapper, ShiroUtils.getUserId()));
            //强制回收内存避免内存溢出
            System.gc();
        } catch (Exception e) {
            e.printStackTrace();
            return "导入失败";
        }
        logService.saveLog("提报计划编辑", "导入并修改提报计划");
        return msg;
    }

    /**
     * 指定功能 -> 导入修改的数据
     *
     * @param file 文件
     * @return 描述
     */
    public String importAndEditAssign(MultipartFile file) {
        try {
            FileUtils.importExcel(file, ExportAssignModel.class, new EditAssignReportPlanListener(reportPlanDao, new ImportCallBack() {
                @Override
                public void onSuccess() {
                    msg = "导入完成";
                }

                @Override
                public void onWarning(List list) {
                    msg = "部份数据无法导入，请点击下载检查数据内容";
                    exportErrorExcelWithUpdate(list);
                }
            }, bReportPlanChangeMapper, ShiroUtils.getUserId()));
        } catch (Exception e) {
            e.printStackTrace();
            String errorMessage = "";
            ExcelDataConvertException edce = (ExcelDataConvertException) e;
            switch (edce.getColumnIndex()) {
                //单价
                case 24:
                    errorMessage = "第"+edce.getRowIndex()+1+"行单价格式不正确，应为数字。";
                    break;
                //数量
                case 25:
                    errorMessage ="第"+edce.getRowIndex()+1+"行数量格式不正确，应为数字。";
                    break;
            }
            return "导入失败，因"+errorMessage;
        }
        logService.saveLog("提报计划编辑", "导入并修改提报计划的指定信息");
        return msg;
    }

    /**
     * 指定库存异常数据导出到Excel
     *
     * @param errorList
     */
    private void exportErrorExcelWithUpdate(List<ExportAssignModel> errorList) {
        if (errorList.size() <= 0) {
            return;
        }
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        String path = uploadPath + user.getAccount() + "/";
        FileUtils.genExcel(path, "error1.xls", ExportAssignModel.class, "未成功导入数据", errorList);
    }

    /**
     * 拆分库存异常数据导出到Excel
     *
     * @param errorList
     */
    private void exportErrorExcelWithSplit(List<ExportDeferralModel> errorList) {
        if (errorList.size() <= 0) {
            return;
        }
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        String path = uploadPath + user.getAccount() + "/";
        FileUtils.genExcel(path, "error1.xls", ExportDeferralModel.class, "未成功导入数据", errorList);
    }

    /**
     * 查询外购件指定列表
     *
     * @return list
     */
    public List<ReportPlanModel> findOutAssignList() {
        return reportPlanDao.findOutAssignList();
    }

    /**
     * 外购件指定
     *
     * @param rppId 提报计划主键
     * @return 行数
     */
    @Transactional(rollbackFor = Exception.class)
    public int outAssign(Integer rppId) {
        BReportPlan plan = bReportPlanMapper.selectByPrimaryKey(rppId);
        reportPlanDao.updatePchangeOrderRppIdByDescAndCode(plan);
        reportPlanDao.updatePInventoryProjectMarkRppIdByDescAndCode(plan);
        plan.setRppIsFlag(1);
        return bReportPlanMapper.updateByPrimaryKey(plan);
    }

    /**
     * 批量外购件指定
     *
     * @param rppIds 提报计划主键数组
     * @return 行数
     */
    @Transactional(rollbackFor = Exception.class)
    public int batchOutAssign(Integer[] rppIds) {
        for (Integer rppId : rppIds) {
            outAssign(rppId);
        }
        return 1;
    }

    /**
     * 根据条件查询采购计划列表
     *
     * @param info 物料描述
     * @return list
     */
    public List<ShoppingPlanModel> findBuyPlanByQuery(String info) {
        return buyPlanDao.findBuyPlanByMatDesc(info);
    }

    /**
     * 指定计划， 修改采购计划为合报状态， 修改提报计划为提交状态，指加入采购计划ID
     *
     * @param rppId 提报ID
     * @param sppId 采购ID
     * @return 行数
     */
    @Transactional(rollbackFor = Exception.class)
    public int assignPlan(Integer rppId, Integer sppId) {
        buyPlanDao.updateIntegraFlagById(1, sppId);
        BReportPlan plan = new BReportPlan();
        plan.setRppId(rppId);
        plan.setRppStatus(3);
        plan.setRppSppId(sppId);
        return bReportPlanMapper.updateByPrimaryKeySelective(plan);
    }

    /**
     * ╭─────────────────────────────────────────────────────────────────────╮
     * │  @方法名: clearAssign                                                │
     * │  @方法说明: 清空指定，把指定状态清除，清除手动指定物料描述内容，清除外购件库│
     * │            串料信息、外购件库库存划项目信息、原料库串料信息、原料库库存划项│
     * │            目信息和成品库库存划项目信息的指定ID列为本计划ID的数据的对应的 │
     * │            ID列数据。                                                │
     * │  @参数说明: [reportPlanModel]  rppId 提报计划主键                     │
     * │  @返回类型说明: com.zhongwang.mms.common.JsonResult                  │
     * │  @作者: 徐一贺                                                       │
     * │  @编程时间: 2020/8/6 10:59                                           │
     * │  @版本号：v1.0                                                       │
     * ╰─────────────────────────────────────────────────────────────────────╯
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult clearAssign(ReportPlanModel reportPlanModel) {
        JsonResult jsonResult = new JsonResult();
        try {
            Integer rppId = reportPlanModel.getRppId();
            reportPlanDao.clearRppIdByPChangeOrder(rppId);
            reportPlanDao.clearRppIdByPInventoryProjectMark(rppId);
            reportPlanDao.clearRppIdByMChangeOrder(rppId);
            reportPlanDao.clearRppIdByMInventoryProjectMark(rppId);
            reportPlanDao.clearRppIdByHInventoryProjectMark(rppId);
            reportPlanDao.clearReportPlanAssign(rppId);
            jsonResult.setType(JsonResult.ResultType.SUCCESS);
            jsonResult.setMsg("清空指定状态成功！");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【异常信息】：" + e.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("清空指定状态失败！");
        }
        return jsonResult;
    }

    /**
     * ╭──────────────────────────────────────────────────────────────────────╮
     * │  @方法名: clearRppId                                                │
     * │  @方法说明: 清空指定的ID                                              │
     * │  @参数说明: [reportPlanModel]  rppId 提报计划主键                     │
     * │  @返回类型说明: com.zhongwang.mms.common.JsonResult                  │
     * │  @作者: 徐一贺                                                       │
     * │  @编程时间: 2020/8/7 16:20                                           │
     * │  @版本号：v1.0                                                       │
     * ╰─────────────────────────────────────────────────────────────────────╯
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult clearRppId(ReportPlanModel reportPlanModel) {
        JsonResult jsonResult = new JsonResult();
        try {
            Integer rppId = reportPlanModel.getRppId();
            reportPlanDao.clearRppIdByPChangeOrder(rppId);
            reportPlanDao.clearRppIdByPInventoryProjectMark(rppId);
            reportPlanDao.clearRppIdByMChangeOrder(rppId);
            reportPlanDao.clearRppIdByMInventoryProjectMark(rppId);
            reportPlanDao.clearRppIdByHInventoryProjectMark(rppId);
            reportPlanDao.clearReportPlanInfo(rppId);
            jsonResult.setType(JsonResult.ResultType.SUCCESS);
            jsonResult.setMsg("清空指定的库存成功！");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【异常信息】：" + e.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("清空指定状态失败！");
        }
        return jsonResult;
    }

    /**
     * @name: deferralExport
     * @description: 导出暂缓列表
     * @param: [response, reportPlanModel]
     * @returnType: void
     * @author: 徐一贺
     * @coddingDate: 2020/8/11 14:46
     * @version: v1.0
     **/
    public void deferralExport(HttpServletResponse response, ReportPlanModel reportPlanModel) {
        List<ExportDeferralModel> list = new ArrayList<>();
        if (reportPlanModel.getRppMatDescArrayStr() != null && !reportPlanModel.getRppMatDescArrayStr().equals("")) {
            String[] strArray = reportPlanModel.getRppMatDescArrayStr().split(",");
            reportPlanModel.setRppMatDescArray(Arrays.asList(strArray));
        }
        if (reportPlanModel.getRppProjectCodeArrayStr() != null && !reportPlanModel.getRppProjectCodeArrayStr().equals("")) {
            String[] strArray = reportPlanModel.getRppProjectCodeArrayStr().split(",");
            reportPlanModel.setRppProjectCodeArray(Arrays.asList(strArray));
        }
        //物控员只能导出自己的计划
        reportPlanModel.setRppPlanner(ShiroUtils.getUser().getName());
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        logService.saveLog("提报计划编辑——拆分导出","用户:【"+user.getName()+"】执行拆分导出操作！");
        String path = uploadPath + user.getAccount() + "/";
        //1.创建临时内存表名
        String tempTableName = "##" + ShiroUtils.getUser().getAccount() + (UUID.randomUUID().toString().replace("-", ""));
        reportPlanModel.setTempTableName(tempTableName);
        //2.查询出数据导入到临时表
        reportPlanDao.createExportDeferralTempTable(reportPlanModel);
        //3.查询临时内存表数据导出
        Integer dataCount = reportPlanDao.getTempTableDataCount(reportPlanModel);
        int step = 5000;
        FileUtils.mkdirs(path);
        // 方法1 如果写到同一个sheet
        path = path + "拆分导出列表.xls";
        ExcelWriter excelWriter = null;
        try {
            // 这里 需要指定写用哪个class去写
            excelWriter = EasyExcel.write(path, ExportDeferralModel.class).build();
            // 这里注意 如果同一个sheet只要创建一次
            WriteSheet writeSheet = EasyExcel.writerSheet("sheet1").build();
            for (int topCount = 5000, notHaveTopCount = 0; notHaveTopCount < dataCount; notHaveTopCount += step) {
                reportPlanModel.setTopCount(topCount);
                reportPlanModel.setNotHaveTopCount(notHaveTopCount);
                list = reportPlanDao.selectExportDeferralTempTableData(reportPlanModel);
                if (list != null) {
                    excelWriter.write(list, writeSheet);
                }
            }
            //4.删除临时内存表
            reportPlanDao.dropExportTempTable(tempTableName);
        } finally {
            // 千万别忘记finish 会帮忙关闭流
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }
        //5.下载
        FileUtils.downloadFile(path, response);
    }

    /**
     * @name: assignDeferralExport
     * @description: 导出批量指定列表
     * @param: [response, reportPlanModel]
     * @returnType: void
     * @author: 徐一贺
     * @coddingDate: 2020/8/11 14:46
     * @version: v1.0
     **/
    public void assignDeferralExport(HttpServletResponse response, ReportPlanModel reportPlanModel) {
        List<ExportAssignModel> list = new ArrayList<>();
        if (reportPlanModel.getRppMatDescArrayStr() != null && !reportPlanModel.getRppMatDescArrayStr().equals("")) {
            String[] strArray = reportPlanModel.getRppMatDescArrayStr().split(",");
            reportPlanModel.setRppMatDescArray(Arrays.asList(strArray));
        }
        if (reportPlanModel.getRppProjectCodeArrayStr() != null && !reportPlanModel.getRppProjectCodeArrayStr().equals("")) {
            String[] strArray = reportPlanModel.getRppProjectCodeArrayStr().split(",");
            reportPlanModel.setRppProjectCodeArray(Arrays.asList(strArray));
        }
        //物控员只能导出自己的计划
        reportPlanModel.setRppPlanner(ShiroUtils.getUser().getName());
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        logService.saveLog("提报计划编辑——指定导出","用户:【"+user.getName()+"】执行指定导出操作！");
        String path = uploadPath + user.getAccount() + "/";
        //1.创建临时内存表名
        String tempTableName = "##" + ShiroUtils.getUser().getAccount() + (UUID.randomUUID().toString().replace("-", ""));
        reportPlanModel.setTempTableName(tempTableName);
        //2.查询出数据导入到临时表
        reportPlanDao.createExportAssignDeferralTempTable(reportPlanModel);
        //3.查询临时内存表数据导出
        Integer dataCount = reportPlanDao.getTempTableDataCount(reportPlanModel);
        int step = 5000;
        FileUtils.mkdirs(path);
        // 方法1 如果写到同一个sheet
        path = path + "指定计划列表.xls";
        ExcelWriter excelWriter = null;
        try {
            // 这里 需要指定写用哪个class去写
            excelWriter = EasyExcel.write(path, ExportAssignModel.class).build();
            // 这里注意 如果同一个sheet只要创建一次
            WriteSheet writeSheet = EasyExcel.writerSheet("sheet1").build();
            for (int topCount = 5000, notHaveTopCount = 0; notHaveTopCount < dataCount; notHaveTopCount += step) {
                reportPlanModel.setTopCount(topCount);
                reportPlanModel.setNotHaveTopCount(notHaveTopCount);
                list = reportPlanDao.selectExportAssignDeferralTempTableData(reportPlanModel);
                if (list != null) {
                    excelWriter.write(list, writeSheet);
                }
            }
            //4.删除临时内存表
            reportPlanDao.dropExportTempTable(tempTableName);
        } finally {
            // 千万别忘记finish 会帮忙关闭流
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }
        //5.下载
        FileUtils.downloadFile(path, response);
    }

    /**
     * @name: deferralErrorLogExport
     * @description: 导出暂缓列表
     * @param: [response, reportPlanModel]
     * @returnType: void
     * @author: 徐一贺
     * @coddingDate: 2020/8/22 12:40
     * @version: v1.0
     **/
    public void deferralErrorLogExport(HttpServletResponse response, ReportPlanModel reportPlanModel) {
        List<ExportDeferralErrorLogModel> list = new ArrayList<>();
        if (reportPlanModel.getRppMatDescArrayStr() != null && !reportPlanModel.getRppMatDescArrayStr().equals("")) {
            String[] strArray = reportPlanModel.getRppMatDescArrayStr().split(",");
            reportPlanModel.setRppMatDescArray(Arrays.asList(strArray));
        }
        if (reportPlanModel.getRppProjectCodeArrayStr() != null && !reportPlanModel.getRppProjectCodeArrayStr().equals("")) {
            String[] strArray = reportPlanModel.getRppProjectCodeArrayStr().split(",");
            reportPlanModel.setRppProjectCodeArray(Arrays.asList(strArray));
        }
        //物控员只能导出自己的计划
        reportPlanModel.setRppPlanner(ShiroUtils.getUser().getName());
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        String path = uploadPath + user.getAccount() + "/";
        //1.创建临时内存表名
        String tempTableName = "##" + ShiroUtils.getUser().getAccount() + (UUID.randomUUID().toString().replace("-", ""));
        reportPlanModel.setTempTableName(tempTableName);
        //2.查询出数据导入到临时表
        reportPlanDao.createDeferralErrorLogExportTempTable(reportPlanModel);
        //3.查询临时内存表数据导出
        Integer dataCount = reportPlanDao.getTempTableDataCount(reportPlanModel);
        int step = 5000;
        FileUtils.mkdirs(path);
        // 方法1 如果写到同一个sheet
        path = path + "暂缓计划错误日志列表.xls";
        ExcelWriter excelWriter = null;
        try {
            // 这里 需要指定写用哪个class去写
            excelWriter = EasyExcel.write(path, ExportDeferralErrorLogModel.class).build();
            // 这里注意 如果同一个sheet只要创建一次
            WriteSheet writeSheet = EasyExcel.writerSheet("sheet1").build();
            for (int topCount = 5000, notHaveTopCount = 0; notHaveTopCount < dataCount; notHaveTopCount += step) {
                reportPlanModel.setTopCount(topCount);
                reportPlanModel.setNotHaveTopCount(notHaveTopCount);
                list = reportPlanDao.selectDeferralErrorLogExportTempTableData(reportPlanModel);
                if (list != null) {
                    excelWriter.write(list, writeSheet);
                }
            }
            //4.删除临时内存表
            reportPlanDao.dropExportTempTable(tempTableName);
        } finally {
            // 千万别忘记finish 会帮忙关闭流
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }
        //5.下载
        FileUtils.downloadFile(path, response);
    }
}
